//
//  InfiniteScrollControl.m
//  Pods
//
//  Created by Liu Zhen on 12/22/15.
//
//

#import "InfiniteScrollControl.h"
#import <ReactiveCocoa/ReactiveCocoa.h>
#import <ReactiveCocoa/RACEXTScope.h>
#import "UITableViewController+InfiniteScroll.h"

static void *InfiniteScrollRACCommandKey = &InfiniteScrollRACCommandKey;
static void *InfiniteScrollDisposableKey = &InfiniteScrollDisposableKey;

@import ObjectiveC.runtime;

@interface InfiniteScrollControl ()

@property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;
@property (nonatomic) UIEdgeInsets originalInset;

@end

@implementation InfiniteScrollControl

- (RACCommand *)rac_command {
    return objc_getAssociatedObject(self, InfiniteScrollRACCommandKey);
}

- (void)setRac_command:(RACCommand *)command {
    objc_setAssociatedObject(self, InfiniteScrollRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    // Dispose of any active command associations.
    [objc_getAssociatedObject(self, InfiniteScrollDisposableKey) dispose];
    
    if (command == nil) return;
    
    // Like RAC(self, enabled) = command.enabled; but with access to disposable.
    RACDisposable *enabledDisposable = [command.enabled setKeyPath:@keypath(self.enabled) onObject:self];
    
    RACDisposable *executionDisposable = [[[[self
                                             rac_signalForControlEvents:UIControlEventValueChanged]
                                            map:^(InfiniteScrollControl *x) {
                                                return [[[command
                                                          execute:x]
                                                         catchTo:[RACSignal empty]]
                                                        then:^{
                                                            return [RACSignal return:x];
                                                        }];
                                            }]
                                           concat]
                                          subscribeNext:^(InfiniteScrollControl *x) {
                                              [x endRefreshing];
                                          }];
    
    RACDisposable *commandDisposable = [RACCompoundDisposable compoundDisposableWithDisposables:@[ enabledDisposable, executionDisposable ]];
    objc_setAssociatedObject(self, InfiniteScrollDisposableKey, commandDisposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)beginRefreshing {
    if (self.controller.infiniteScroll) {
        self.isLoading = YES;
        [self.activityIndicatorView startAnimating];
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
}

- (void)endRefreshing {
    
    if (self.controller.infiniteScroll) {
        self.controller.infiniteScroll = NO;
        self.isLoading = NO;
        [self.activityIndicatorView stopAnimating];
        @weakify(self);
        [UIView animateWithDuration:0.3 animations:^{
            @strongify(self);
            self.controller.tableView.contentInset = self.originalInset;
        }];
    }
}

- (id)initWithFrame:(CGRect)frame {
    if(self = [super initWithFrame:frame]) {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        self.enabled = YES;
        self.backgroundColor = [UIColor greenColor];
    }
    return self;
}

- (void)layoutSubviews {
    self.activityIndicatorView.center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
}

- (UIActivityIndicatorView *)activityIndicatorView {
    if(!_activityIndicatorView) {
        _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        _activityIndicatorView.hidesWhenStopped = YES;
        _activityIndicatorView.backgroundColor = [UIColor redColor];
        [self addSubview:_activityIndicatorView];
    }
    return _activityIndicatorView;
}

@end
